﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Resources;
using System.Drawing;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Net;
using System.Xml.Linq;

namespace AMPLibrary.LastFM
{
    [Serializable]
    public class LastFMArtistInformation
    {
        public string ArtistName
        {
            get;
            set;
        }

        public string ImageSmallURL
        {
            get;
            private set;
        }

        public string ImageMediumURL
        {
            get;
            set;
        }

        public string ImageLargeURL
        {
            get;
            set;
        }

        public string ImageExtraLargeURL
        {
            get;
            set;
        }

        public string ImageMegaURL
        {
            get;
            set;
        }

        public List<string> SimilarArtists
        {
            get;
            set;
        }

        public List<string> TopTracks
        {
            get;
            set;
        }

        public List<string> Tags
        {
            get;
            set;
        }

        public List<LastFMEventInformation> UpcommingEvents
        {
            get;
            set;
        }

        public string BioShort
        {
            get;
            set;
        }

        public string BioLong
        {
            get;
            set;
        }

        public string BioPublishedDateTime
        {
            get;
            set;
        }
        
        public bool HasInformation
        {
            get
            {
                if (this.ArtistName != string.Empty &&
                    this.BioShort != string.Empty &&
                    this.BioLong != string.Empty &&
                    this.ImageSmallURL != string.Empty &&
                    this.ImageMediumURL != string.Empty &&
                    this.ImageLargeURL != string.Empty &&
                    this.ImageExtraLargeURL != string.Empty &&
                    this.ImageMegaURL != string.Empty &&
                    this.SimilarArtists.Count != 0 &&
                    this.TopTracks.Count != 0 &&
                    this.Tags.Count != 0)
                    return true;

                return false;
            }
            private set
            {
            }
        }

        public LastFMArtistInformation()
        {
            this.ArtistName = string.Empty;
            this.ImageExtraLargeURL = string.Empty;
            this.ImageLargeURL = string.Empty;
            this.ImageMediumURL = string.Empty;
            this.ImageMegaURL = string.Empty;
            this.ImageSmallURL = string.Empty;
            this.BioShort = string.Empty;
            this.BioLong = string.Empty;
            this.Tags = new List<string>();
            this.TopTracks = new List<string>();
            this.SimilarArtists = new List<string>();
            this.UpcommingEvents = new List<LastFMEventInformation>();
            this.HasInformation = false;
            this.BioPublishedDateTime = string.Empty;
        }

        public void TryPopulateLastFMArtistInformation(string artistName)
        {
            WebClient webClient = new WebClient();

            TextReader textReader = null;
            XDocument xmlDocument = null;

            try
            {
                /*************** ARTIST INFORMATION ****************/
                string lastFMArtistXML = webClient.DownloadString("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist=" + artistName + "&api_key=dc8176d24da81ad74f1f11585befac52");
                textReader = new StringReader(lastFMArtistXML);
                xmlDocument = XDocument.Load(textReader);

                this.ArtistName = (from a in xmlDocument.Descendants("artist") select a.Element("name")).FirstOrDefault().Value;

                int i = 0;
                foreach (string imageURL in (from a in xmlDocument.Descendants("image") select a.Value))
                {
                    if(i == 0)
                        this.ImageExtraLargeURL = imageURL;

                    if (i == 1)
                        this.ImageLargeURL = imageURL;

                    if (i == 2)
                        this.ImageMediumURL = imageURL;
                    
                    if (i == 3)
                        this.ImageMegaURL = imageURL;

                    if (i == 4)
                    {
                        this.ImageSmallURL = imageURL;
                        break;
                    }

                    i++;
                }

                foreach (string similarArtist in (from a in xmlDocument.Descendants("similar").Descendants("artist") select a.Element("name")))
                {
                    if (similarArtist != null)
                        this.SimilarArtists.Add(similarArtist);
                }

                foreach (string tag in (from a in xmlDocument.Descendants("tags").Descendants("tag") select a.Element("name")))
                {
                    if (tag != null)
                        this.Tags.Add(tag);
                }

                this.BioShort = LastFMHelper.RemoveHTML((from a in xmlDocument.Descendants("bio") select a.Element("summary")).Single().ToString());
                this.BioLong = LastFMHelper.RemoveHTML((from a in xmlDocument.Descendants("bio") select a.Element("content")).Single().ToString());
                this.BioPublishedDateTime = LastFMHelper.RemoveHTML((from a in xmlDocument.Descendants("bio") select a.Element("published")).Single().ToString());
                
                if (xmlDocument != null)
                    xmlDocument = null;

                if (textReader != null)
                    textReader.Close();
                                
                /*************** TRACK INFORMATION ****************/
                string lastFMArtistTopTracksXML = webClient.DownloadString("http://ws.audioscrobbler.com/2.0/?method=artist.gettoptracks&artist=" + artistName + "&api_key=dc8176d24da81ad74f1f11585befac52");
                textReader = new StringReader(lastFMArtistTopTracksXML);
                xmlDocument = XDocument.Load(textReader);

                TopTracks.Clear();


                foreach (string topTrack in (from a in xmlDocument.Descendants("toptracks").Descendants("track") select a.Element("name")))
                {
                    if (topTrack != null)
                        this.TopTracks.Add(topTrack);
                }

                if (xmlDocument != null)
                    xmlDocument = null;

                if (textReader != null)
                    textReader.Close();

                /************** EVENT INFORMATION *****************/
                string lastFMEventXML = webClient.DownloadString("http://ws.audioscrobbler.com/2.0/?method=artist.getevents&artist=" + artistName + "&api_key=dc8176d24da81ad74f1f11585befac52");
                textReader = new StringReader(lastFMEventXML);
                xmlDocument = XDocument.Load(textReader);

                UpcommingEvents.Clear();

                foreach (XElement element in (from e in xmlDocument.Descendants("events").Descendants("event") select e).Take(8))
                {
                    if (element != null)
                    {
                        LastFMEventInformation lfmei = new LastFMEventInformation();

                        XElement x = element.Element("id");

                        lfmei.EventId = long.Parse(x.Value);
                        lfmei.Title = element.Element("title").Value;

                        lfmei.VenueName = element.Element("venue").Element("name").Value;
                        lfmei.City = element.Element("venue").Element("location").Element("city").Value;
                        lfmei.Country = element.Element("venue").Element("location").Element("country").Value;

                        try
                        {
                            lfmei.StartDate = element.Element("startDate").Value;
                        }
                        catch
                        {
                        }

                        try
                        {
                            lfmei.StartTime = element.Element("startTime").Value;
                        }
                        catch
                        {
                        }

                        try
                        {
                            lfmei.EndDate = element.Element("endDate").Value;
                        }
                        catch
                        {
                        }

                        try
                        {
                            lfmei.EndTime = element.Element("endTime").Value;
                        }
                        catch
                        {
                        }

                        lfmei.Headliner = element.Element("artists").Element("headliner").Value;

                        foreach (XElement _artistName in (from ele in element.Element("artists").Elements("artist") select ele).Take(8))
                            lfmei.Artists.Add(_artistName.Value);

                        if (lfmei.Artists.Count == 8)
                            lfmei.Artists.Add("and more ....");

                        this.UpcommingEvents.Add(lfmei);
                    }
                }

                if (xmlDocument != null)
                    xmlDocument = null;

                if (textReader != null)
                    textReader.Close();
            }
            catch
            {

            }
            finally
            {
                if (xmlDocument != null)
                    xmlDocument = null;

                if (textReader != null)
                    textReader.Close();
            }
        }
    }
}
